package bg.btanev.eightyfour.gwtfacade.commandhandler;

import org.apache.commons.lang.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import bg.btanev.eightyfour.domain.Target;
import bg.btanev.eightyfour.domain.person.Person;
import bg.btanev.eightyfour.gwtfacade.converter.DtoConverter;
import bg.btanev.eightyfour.service.PersonService;
import bg.btanev.eightyfour.service.TargetService;
import bg.btanev.eightyfour.shared.command.CommandResult;
import bg.btanev.eightyfour.shared.command.person.FindPersonCommand;
import bg.btanev.eightyfour.shared.command.person.FindPersonInput;
import bg.btanev.eightyfour.shared.dto.person.PersonDto;

/**
 *
 * @author B.Tanev
 *
 */
public class FindPersonCommandHandler extends
		GenericCommandHandler<FindPersonInput, PersonDto, CommandResult<FindPersonInput, PersonDto>, FindPersonCommand> {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = LoggerFactory.getLogger(FindPersonCommandHandler.class);

	private final PersonService personService;
	private final TargetService targetService;
	private final DtoConverter converter;

	public FindPersonCommandHandler(PersonService personService, TargetService targetService, DtoConverter converter) {
		super();

		Validate.notNull(personService);
		Validate.notNull(targetService);
		Validate.notNull(converter);

		this.personService = personService;
		this.targetService = targetService;
		this.converter = converter;
	}

	@Override
	protected PersonDto doExecuteInternal(FindPersonInput attachedInput) {
		Validate.notNull(attachedInput);

		Long personId = attachedInput.getPersonId();
		String email = attachedInput.getEmail();
		Long targetId = attachedInput.getTargetId();

		Person person = null;
		if (personId != null && personId.longValue() > 0) {
			person = personService.findByIdentifier(personId);
		} else if (email != null && email.length() > 0) {
			person = personService.findByEmail(email);
		} else if (targetId != null && targetId.longValue() > 0) {
			Target target = targetService.findByIdentifier(targetId);
			if (target != null) {
				person = target.getPerson();
			}
		}

		PersonDto personDto = null;
		if (person != null) {
			personDto = converter.domainToDto(person, 2);
		} else {
			logger.info("doExecuteInternal(FindPersonInput) - no person found for: {}", attachedInput); //$NON-NLS-1$
		}

		return personDto;
	}

	@Override
	protected CommandResult<FindPersonInput, PersonDto> packCommandResult(FindPersonInput input,
			PersonDto detachedResult) {

		return new CommandResult<FindPersonInput, PersonDto>(input, detachedResult);
	}

	@Override
	public FindPersonInput attach(FindPersonInput input) {
		return input;
	}

	@Override
	public PersonDto detach(PersonDto result) {
		return result;
	}
}
